package com.dong.netty.client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.json.JsonObjectDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


/**
 * @author dengxiudong
 */
@SpringBootApplication
public class NettyClientApplication implements ApplicationRunner
{

    public static void main(String[] args)
    {
        SpringApplication.run(NettyClientApplication.class, args);
    }

    @Override
    public void run(ApplicationArguments args) throws Exception
    {
        // 用于客户端处理网络事件的线程组
        EventLoopGroup group = new NioEventLoopGroup();
        try {
            Bootstrap b = new Bootstrap();
            b.group(group)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>()
                    {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception
                        {
                            // 添加日志处理器
                            ch.pipeline().addLast(new LoggingHandler(LogLevel.DEBUG));
                            // 解码收到的JSON字符串为JsonObject
                            ch.pipeline().addLast(new JsonObjectDecoder());
                            // 将收到的对象转换为字符串
                            ch.pipeline().addLast(new StringDecoder());
                            // 编码发送的字符串为JSON
                            ch.pipeline().addLast(new StringEncoder());
                            // 自定义的客户端处理器
                            ch.pipeline().addLast(new NettyClientHandler());
                        }
                    });

            // 发起异步连接操作
            ChannelFuture f = b.connect("localhost", 10097).sync();

            // 等待连接关闭
            f.channel().closeFuture().sync();
        } finally {
            // 优雅退出，释放线程池资源
            group.shutdownGracefully();
        }
    }
}
